package com.googlecode.derby.customize;

import java.util.Calendar;
import java.util.Map;
import java.util.WeakHashMap;

import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * SQL・SELECTにて取得されたデータを格納クラス.
 *
 * @author o.tanaka
 * @version 2009/12/11
 */
public class ResultData {

    private Map<String, Object> mapData;

    /**
     * WAVE DASHキャラクタコード(Unicode).
     */
    private static final char WAVE_DASH = 0x301c;

    /**
     * FULLWIDTH TILDEキャラクタコード(Unicode).
     */
    private static final char FULLWIDTH_TILDE = 0xff5e;

    /**
     * 項目データを一緒に生成する。（WeakHashMap）.
     */
    public ResultData() {
        this.mapData = new WeakHashMap<String, Object>();
    }

    /**
     * 生成済みの項目データをセットする.
     *
     * @param theMapDatas
     *            取得された項目データのセット（WeakHashMap）
     */
    public ResultData(final WeakHashMap<String, Object> theMapDatas) {
        this.mapData = theMapDatas;
    }

    /**
     * WAVE_DASHをFULLWIDTH_TILDEへ変換します.
     *
     * @param str
     *            入力文字列
     * @return 変換後出力文字列
     */
    private String convWaveDash(final String str) {
        if (str == null) {
            return null;
        }
        final StringBuilder sb = new StringBuilder();
        char c;
        for (int i = 0; i < str.length(); i++) {
            c = str.charAt(i);
            if (c == ResultData.WAVE_DASH) {
                sb.append(ResultData.FULLWIDTH_TILDE);
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 指定された項目列のデータをCalendarにて取得する.
     *
     * @param theKey
     *            項目名
     * @return 項目列名にセットされているデータ
     */
    public final Calendar getCalendar(final String theKey) {
        Calendar cal = null;
        if (this.mapData.get(theKey) != null) {
            cal = Calendar.class.cast(this.mapData.get(theKey));
        }
        return cal;
    }

    /**
     * 指定された項目列のデータを取得する.
     *
     * @param theKey
     *            項目名
     * @return 項目列名にセットされているデータ
     */
    public final Object getData(final String theKey) {
        return this.mapData.get(theKey);
    }

    /**
     * @return 項目データの取得
     */
    public final Map<String, Object> getMapDatas() {
        return this.mapData;
    }

    /**
     * 指定された項目列のデータをCalendarにて取得する.
     *
     * @param theKey
     *            項目名
     * @return 項目列名にセットされているデータ
     */
    public final double getParseDouble(final String theKey) {
        double d = 0D;
        if (this.mapData.get(theKey) != null) {
            d = Double.parseDouble(this.getString(theKey));
        }
        return d;
    }

    /**
     * 指定された項目列のデータをCalendarにて取得する.
     *
     * @param theKey
     *            項目名
     * @return 項目列名にセットされているデータ
     */
    public final long getParseLong(final String theKey) {
        long l = 0L;
        if (this.mapData.get(theKey) != null) {
            l = (long) Double.parseDouble(this.getString(theKey));
        }
        return l;
    }

    /**
     * 指定された項目列のデータをStringにて取得する.
     *
     * @param theKey
     *            項目名
     * @return 項目列名にセットされているデータ
     */
    public final String getString(final String theKey) {
        String str = null;
        if (this.mapData.get(theKey) != null) {
            str = this.convWaveDash(
                    String.valueOf(this.mapData.get(theKey)));
        }
        return str;
    }

    /**
     * 指定された項目列にデータをセットする.
     *
     * @param theKey
     *            項目名
     * @param theData
     *            値
     */
    public final void setData(
            final String theKey,
            final Object theData) {
        this.mapData.put(theKey, theData);
    }

    /**
     * @param theMapDatas
     *            取得された項目データのセット（Map）
     */
    public final void setDatas(final Map<String, Object> theMapDatas) {
        this.mapData = theMapDatas;
    }

    /**
     * @return toArray
     */
    public Object[] toArray() {
        return this.mapData.values().toArray();
    }

    /**
     * @return ToStringBuilder.reflectionToString(this);
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}
